package eu.testing.system.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

import eu.testing.system.controllers.SystemController;
import eu.testing.system.dao.AnswerDao;
import eu.testing.system.dao.AssignedDao;
import eu.testing.system.dao.ResultDao;
import eu.testing.system.dao.TestDao;
import eu.testing.system.models.Answer;
import eu.testing.system.models.Question;
import eu.testing.system.models.Result;
import eu.testing.system.models.Test;
import eu.testing.system.models.Variant;

public class ResultDaoImpl extends SimpleJdbcDaoSupport implements ResultDao {
	private static final String SQL_INSERT = "INSERT INTO result (USERNAME,TEST_ID,TEST_TITLE, SCORE) VALUES (?, ?, ?, ?)";
	private static final String SQL_SELECT = "SELECT * FROM test WHERE USERNAME = ? AND TEST_ID = ?";
	private static final String SQL_UPDATE = "UPDATE result SET USERNAME = ?, TEST_ID = ?, TEST_TITLE = ?, TIMESTAMP = ?, SCORE = ? WHERE TEST_ID = ?";
	private static final String SQL_SELECT_ALL = "SELECT * FROM result WHERE USERNAME = ?";
	SystemController controller = new SystemController();


	@Override
	public void insertResult(Result result) {
		getJdbcTemplate().update(SQL_INSERT, result.getUsername(),
				result.getTestId(), result.getTestTitle(), result.getScore());
		for (Answer answer : result.getAnswers()) {
			controller.answerDao.insertAnswer(answer);
		}

	}

	@Override
	public Result getResult(String username, int testId) {
		return getSimpleJdbcTemplate().queryForObject(SQL_SELECT,
				new ResultParameterizedRowMapper(), username, testId);

	}

	@Override
	public void editResult(Result result) {
		getJdbcTemplate().update(SQL_UPDATE, result.getUsername(),
				result.getTestId(), result.getTime(), result.getScore());

	}

	@Override
	public List<Result> getAllResults(String username) {
		List<Result> results = getSimpleJdbcTemplate().query(SQL_SELECT_ALL,
				new ResultParameterizedRowMapper(), username);
		return results;
	}

	@Override
	public Result analyzeAnswers(String username, Test submitedTest)
			throws SQLException {
		List<Answer> answers = new ArrayList<Answer>();
		Test originalTest = controller.testDao.getTest(submitedTest.getId());
		List<Question> originalQuestionData = originalTest.getQuestions();
		List<Question> submitedQuestionData = submitedTest.getQuestions();
		int numberOfCorrectAnswers = 0;
		int numberOfAnswers = 0;
		for (int i = 0; i < originalQuestionData.size(); i++) {
			Question questionOriginal = originalQuestionData.get(i);
			Question questionSubmited = submitedQuestionData.get(i);
			numberOfAnswers += questionOriginal.getVariants().size();
			for (int j = 0; j < questionOriginal.getVariants().size(); j++) {
				boolean truth = false;
				Variant variantOriginal = questionOriginal.getVariants().get(j);
				Variant variantSubmited = questionSubmited.getVariants().get(j);
				if (variantOriginal.isTruth() == variantSubmited.isTruth()) {
					truth = true;
					numberOfCorrectAnswers += 1;
				}
				Answer answer = new Answer(username, submitedTest.getId(), i,
						j, truth);
				answers.add(answer);
			}
		}
		return createResult(username, numberOfCorrectAnswers, numberOfAnswers,
				answers, submitedTest.getId(), submitedTest.getTitle());
	}

	private Result createResult(String username, int numberOfCorrectAnswers,
			int numberOfAnswers, List<Answer> answers, int testId,
			String testTitle) {
		int score = numberOfCorrectAnswers * 100 / numberOfAnswers;
		if (score > 50) {
			controller.assignedDao.deleteAssigned(username);

		}
		Result results = new Result();
		results.setUsername(username);
		results.setAnswers(answers);
		results.setScore(score);
		results.setTestId(testId);
		results.setTestTitle(testTitle);
		return results;

	}

	public class ResultParameterizedRowMapper implements
			ParameterizedRowMapper<Result> {
		@Override
		public Result mapRow(ResultSet rs, int rowNum) throws SQLException {
			Result result = new Result();
			result.setUsername(rs.getString("USERNAME"));
			result.setTestId(rs.getInt("TEST_ID"));
			result.setTestTitle(rs.getString("TEST_TITLE"));
			result.setTime(rs.getDate("TIMESTAMP"));
			result.setScore(rs.getInt("SCORE"));
			return result;
		}

	}

}
